﻿Imports System.IO
Imports System.Text
Imports NewHeaderSystems.Archive.Data
Imports NewHeaderSystems.Archive.Types

Public Class AplProcessor
    Inherits BaseProcessor

    Public Function Process(ByVal sourceFilePath As String, ByVal userID As Integer) As Integer
        Dim confirmsList As New List(Of TradeSuite)
        BackgroundReporter.MessagePrefix = Path.GetFileName(sourceFilePath)
        For Each page In GetPageList(sourceFilePath)
            Dim tradeSuite As TradeSuite = ParseAPLConfirm(page)
            BackgroundReporter.ReportProgress(tradeSuite.ToString())
            FindMatch(tradeSuite)
            confirmsList.Add(tradeSuite)
        Next
        BackgroundReporter.ReportProgress("Saving confirms...")
        Return Save(confirmsList, userID, sourceFilePath)
    End Function

    Private Function GetPageList(ByVal fileName As String) As List(Of String)
        Dim reader As New StreamReader(New FileStream(fileName, FileMode.Open, FileAccess.Read))
        Dim line As String

        Do
            line = reader.ReadLine()
        Loop Until line Is Nothing OrElse line.Contains("PAGE") ' Get to the actual confirms
        If Not line Is Nothing Then
            If line.Length > 0 And line.Chars(0) = Nothing Then 'HACK: The first null character prevents the line from being read.
                line = line.Substring(1) 'Skip the null character
            End If
        End If
        ' Make a string out of the whole Confirm
        ' When the program gets here the first line of the confirm is in the line
        Dim pageList As New List(Of String)
        Dim page As New StringBuilder

        Do While Not line Is Nothing
            page.AppendLine(line)
            line = reader.ReadLine()
            Dim isEndOfPage = (line Is Nothing) OrElse (line.Contains(" PAGE ") And line.Contains(" OF ") And line.Contains("DTC"))
            'Add the page when we reach a new page marker of it is end of file.
            If isEndOfPage Then
                pageList.Add(page.ToString())
                page = New StringBuilder()
            End If
        Loop

        reader.Close()
        Return pageList
    End Function

    ''' <summary>
    ''' Find the account id and ticker symbol either from the match table (if apl) or security and account
    ''' </summary>
    ''' <param name="tradeSuite"></param>
    ''' <returns>Returns true if a match is found</returns>
    ''' <remarks></remarks>
    Public Shared Function FindMatch(ByRef tradeSuite As TradeSuite) As Boolean
        If (tradeSuite.Source = "APL") Then ' try the match table
            DataScript.UpdateTradeFromMatch(tradeSuite)
        End If

        If tradeSuite.AccountID = "" Then ' try the reference tables
            DataScript.UpdateTradeFromAccount(tradeSuite)
        End If

        If tradeSuite.TickerSymbol = "" Then
            DataScript.UpdateTradeFromSecurity(tradeSuite)
        End If
        Return tradeSuite.AccountID <> "" And tradeSuite.TickerSymbol <> ""
    End Function


    Private Function ParseAPLConfirm(ByVal TempTxt As String) As TradeSuite

        Dim TSRec As New TradeSuite
        Dim tmpMarker1 As Integer
        Dim tmpMarker2 As Integer
        Dim tmpTxt, tmpStr As String
        Dim tf As String

        tmpTxt = TempTxt

        TSRec.Source = "APL"
        TSRec.AccountID = "" ' needs to be looked up
        TSRec.TickerSymbol = "" ' needs to be looked up

        ' grab header line here
        TSRec.HeadingLine = Mid(tmpTxt, 1, 80)

        tmpMarker1 = InStr(tmpTxt, "CUSIP/DES") - 23 ' the length of "CUSIP/ID" string - 23
        tmpMarker2 = tmpMarker1 + 6
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.Side = tf

        ' Get The CUSIP
        tmpMarker1 = InStr(tmpTxt, "CUSIP/DES") + 10 ' the length of "CUSIP/ID" string + 1
        tmpMarker2 = InStr(tmpTxt, "TRADE DATE")
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.SecurityID = tf

        ' Get the trade date
        tmpMarker1 = InStr(tmpTxt, "TRADE DATE") + 11 ' the length of "TRADE DATE" string + 1
        tmpMarker2 = InStr(tmpTxt, "SETTLEMENT")
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.TradeDate = tf

        ' get settlement here
        tmpMarker1 = InStr(tmpTxt, "SETTLEMENT") + 11
        tmpStr = Mid(tmpTxt, tmpMarker1, 12)
        TSRec.SettlementDate = tf

        ' Executing broker
        tmpMarker1 = InStr(tmpTxt, "FROM   ") + 8
        tmpMarker2 = InStr(tmpTxt, "FROM   ") + 19
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.BkrDlrNum = tf

        ' Executing broker name
        tmpMarker1 = InStr(tmpTxt, "FROM   ") + 19
        tmpMarker2 = InStr(tmpTxt, "DTC BKR")
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        tf = Replace(tf, vbCrLf, "")
        TSRec.BkrDlrName = tf

        ' Clearing broker
        tmpMarker1 = InStr(tmpTxt, "DTC BKR") + 8
        tmpMarker2 = InStr(tmpTxt, "DTC BKR") + 19
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.ClrAgtNum = tf

        ' Clearing broker name
        tmpMarker1 = InStr(tmpTxt, "DTC BKR") + 19
        tmpMarker2 = InStr(tmpTxt, "B/D INT ACCT")
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        tf = Replace(tf, vbCrLf, "")
        TSRec.ClrAgtName = tf

        'B/DInternal Account Number is only on the confirm
        tmpMarker1 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 33
        tmpMarker2 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 48
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.BkrDlrAccountNum = tf

        'Agt Internal Account Number is only on the confirm
        tmpMarker1 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 49
        tmpMarker2 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 61
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.AgtAccountNum = tf

        'Agt num
        tmpMarker1 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 62
        tmpMarker2 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 71
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.AgtNum = tf

        ' Role
        tmpMarker1 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 71
        tmpMarker2 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 76
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.Role = tf

        ' Market
        tmpMarker1 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 76
        tmpMarker2 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 81
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.Market = tf

        ' Account type
        tmpMarker1 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 81
        tmpMarker2 = InStr(tmpTxt, "ACCT TYPE  SIDE") + 93
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = tmpStr
        tf = Trim(tmpStr)
        TSRec.AccountType = tf

        'Firm DTC ID
        tmpMarker1 = InStr(tmpTxt, "TO  ") + 8
        tmpMarker2 = InStr(tmpTxt, "TO  ") + 19
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = tmpStr
        tf = Trim(tmpStr)
        TSRec.InstitutionID = tf

        'Firm name
        tmpMarker1 = InStr(tmpTxt, "TO  ") + 19
        tmpMarker2 = InStr(tmpTxt, "/") - 3
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.InstitutionName = tf

        ' issue description
        tmpMarker1 = InStr(tmpTxt, "SETTLEMENT") + 35
        tmpStr = Mid(tmpTxt, tmpMarker1, 80)
        tf = Trim(tmpStr)
        TSRec.SecurityDescription = tf

        ' issue description 2
        tmpMarker1 = tmpMarker1 + 83
        tmpStr = Mid(tmpTxt, tmpMarker1, 80)
        tf = Trim(tmpStr)
        TSRec.SecurityDescription2 = tf

        ' issue description 3
        tmpMarker1 = tmpMarker1 + 83
        tmpStr = Mid(tmpTxt, tmpMarker1, 80)
        tf = Trim(tmpStr)
        TSRec.SecurityDescription3 = tf

        tmpMarker1 = InStr(tmpTxt, "CONF #")
        tmpTxt = Mid(TempTxt, tmpMarker1, Len(TempTxt))

        'DTCConfirm num
        tmpMarker1 = InStr(tmpTxt, "CONF #") + 6
        tmpStr = Mid(tmpTxt, tmpMarker1, 20)
        tf = Trim(tmpStr)
        TSRec.ControlNum = tf

        'Quantity
        tmpMarker1 = InStr(tmpTxt, "QNTY  ") + 6
        tmpStr = Mid(tmpTxt, tmpMarker1, 20)
        tf = Trim(tmpStr)
        TSRec.Units = tf

        'Interested party 1
        tmpMarker1 = InStr(tmpTxt, "INT PTY 1") + 10
        tmpStr = Mid(tmpTxt, tmpMarker1, 10)
        tf = Trim(tmpStr)
        TSRec.InterestedParty1 = tf

        'Interested Party Name 1
        tmpMarker1 = InStr(tmpTxt, "PRICE    ") + 28
        tmpStr = Mid(tmpTxt, tmpMarker1, 35)
        tf = Trim(tmpStr)
        TSRec.InterestedParty1Name = tf

        'Price
        tmpMarker1 = InStr(tmpTxt, "PRICE    ") + 7
        tmpStr = Mid(tmpTxt, tmpMarker1, 19)
        tf = Trim(tmpStr)
        TSRec.PricePerShare = tf

        'Net price
        tmpMarker1 = InStr(tmpTxt, "NET PRICE") + 10
        tmpStr = Mid(tmpTxt, tmpMarker1, 16)
        tf = Trim(tmpStr)
        TSRec.NetPrice = tf

        'Principal
        tmpMarker1 = InStr(tmpTxt, "PRINC   ") + 6
        tmpStr = Mid(tmpTxt, tmpMarker1, 20)
        tf = Trim(tmpStr)
        TSRec.Principal = tf

        'Interested party 2
        tmpMarker1 = InStr(tmpTxt, "INT PTY 2") + 10
        tmpStr = Mid(tmpTxt, tmpMarker1, 10)
        tf = Trim(tmpStr)
        TSRec.InterestedParty2 = tf

        'Interested Party Name 2
        tmpMarker1 = InStr(tmpTxt, "REG/SHP") + 27
        tmpStr = Mid(tmpTxt, tmpMarker1, 35)
        tf = Trim(tmpStr)
        TSRec.InterestedParty2Name = tf

        'REG/SHP
        tmpMarker1 = InStr(tmpTxt, "REG/SHP") + 7
        tmpStr = Mid(tmpTxt, tmpMarker1, 19)
        tf = Trim(tmpStr)
        TSRec.Reg_Shp = tf

        'INTEREST
        tmpMarker1 = InStr(tmpTxt, "INTEREST") + 8
        tmpStr = Mid(tmpTxt, tmpMarker1, 18)
        tf = Trim(tmpStr)
        TSRec.AccruedInterest = tf

        'TAXES
        tmpMarker1 = InStr(tmpTxt, "TAXES") + 5
        tmpStr = Mid(tmpTxt, tmpMarker1, 21)
        tf = Trim(tmpStr)
        TSRec.Taxes = tf

        'Commision
        tmpMarker1 = InStr(tmpTxt, "COMM  ") + 4
        tmpStr = Mid(tmpTxt, tmpMarker1, 22)
        tf = Trim(tmpStr)
        tf = tmpStr
        TSRec.Commission = tf

        'OTHER
        tmpMarker1 = InStr(tmpTxt, "OTHER") + 5
        tmpStr = Mid(tmpTxt, tmpMarker1, 21)
        tf = Trim(tmpStr)
        TSRec.OtherCharges = tf

        'NET AMT
        tmpMarker1 = InStr(tmpTxt, "NET AMT") + 7
        tmpStr = Mid(tmpTxt, tmpMarker1, 19)
        tf = Trim(tmpStr)
        TSRec.NetAmount = tf

        ' Get Control Number (11)
        tmpMarker1 = InStr(tmpTxt, "CONTROL #") + 13
        ' get to the front of the control number
        tmpMarker2 = InStr(tmpTxt, "CONTROL #") + 28
        ' get to the end of the control number
        tmpStr = Mid(tmpTxt, tmpMarker1, tmpMarker2 - tmpMarker1)
        tf = Trim(tmpStr)
        TSRec.DTCControlNumber = tf

        'Get AffirmStatus       
        If InStr(tmpTxt, "TRADE NOT AFFIRMABLE") > 0 Then
            TSRec.AffirmStatus = "TRADE NOT AFFIRMABLE"
        Else
            TSRec.AffirmStatus = "AFFIRM BY 12:00 PM EST"
        End If

        'Special Instruction 1     
        If InStr(tmpTxt, "AFFIRM BY ") > 0 Then
            tmpMarker1 = InStr(tmpTxt, "AFFIRM BY ") + 53
        Else
            tmpMarker1 = InStr(tmpTxt, "TRADE NOT AFFIRMABLE ") + 53
        End If
        tmpStr = Mid(tmpTxt, tmpMarker1, 50)
        tf = Trim(tmpStr)
        TSRec.SpecialInstr1 = tf

        'Special Instruction 2
        tmpMarker1 = tmpMarker1 + 83
        tmpStr = Mid(tmpTxt, tmpMarker1, 50)
        tf = Trim(tmpStr)
        TSRec.SpecialInstr2 = tf

        'Special Instruction 3
        tmpMarker1 = tmpMarker1 + 83
        tmpStr = Mid(tmpTxt, tmpMarker1, 50)
        tf = Trim(tmpStr)
        TSRec.SpecialInstr3 = tf

        'Special Instruction 4
        tmpMarker1 = tmpMarker1 + 83
        tmpStr = Mid(tmpTxt, tmpMarker1, 50)
        tf = Trim(tmpStr)
        TSRec.SpecialInstr4 = tf

        'Special Instruction 5
        tmpMarker1 = tmpMarker1 + 83
        tmpStr = Mid(tmpTxt, tmpMarker1, 50)
        tf = Trim(tmpStr)
        TSRec.SpecialInstr5 = tf

        Return TSRec
    End Function
End Class
